' clUsuarioAD
Imports bitworksComunesV3.Datos
Imports System.DirectoryServices
Imports System.DirectoryServices.DirectoryEntry
Imports System.Text
Public Class clUsuarioAD
    Implements IComparable
    Dim _nombreCompleto As String
    Dim _usuario As String
    Dim _userAccountControl As Integer
    Dim _email As String
    Dim _userPrincipalName As String
    Dim _company As String
    Dim _homephone As String
    Dim _mobile As String
    Dim _streetAddress As String

#Region "Propiedades"
    Public Property Usuario() As String
        Get
            Return _usuario.ToUpper
        End Get
        Set(ByVal value As String)
            _usuario = value.ToUpper
        End Set
    End Property
    Public Property nombreCompleto() As String
        Get
            Return _nombreCompleto
        End Get
        Set(ByVal value As String)
            _nombreCompleto = value
        End Set
    End Property

    Public ReadOnly Property userAccountControl() As Integer
        Get
            Return _userAccountControl
        End Get
    End Property
    Public ReadOnly Property email() As String
        Get
            Return _email
        End Get
    End Property
    Public ReadOnly Property userPrincipalName() As String
        Get
            Return _userPrincipalName
        End Get
    End Property
    Public ReadOnly Property company() As String
        Get
            Return _company
        End Get
    End Property
    Public ReadOnly Property homephone() As String
        Get
            Return _homephone
        End Get
    End Property
    Public ReadOnly Property mobil() As String
        Get
            Return _mobile
        End Get
    End Property
    Public ReadOnly Property streetAddress() As String
        Get
            Return _streetAddress
        End Get
    End Property
#End Region

#Region "Constructores"
    Public Sub New()

    End Sub
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="usuario">Nombre de Usuario incluido el dominio</param>
    ''' <param name="user">Nombre de usuario sin dominio</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal usuario As String, Optional ByVal user As String = "")
        Dim usertemp As String = ""
        Dim arrUser() As String = Split(usuario, "\")
        If arrUser.Length > 1 Then
            usertemp = arrUser.GetValue(1)
        Else
            usertemp = arrUser.GetValue(0)
        End If
        _usuario = usuario
        cargarDatos(usertemp)
    End Sub
#End Region

    Public Overrides Function ToString() As String
        Return _usuario
    End Function

    ''' <summary>
    ''' Genera una conexion al active directory
    ''' </summary>
    ''' <returns>DirectoryEntry</returns>
    Public Shared Function GetDirectoryEntry() As DirectoryEntry
        Dim de As New DirectoryEntry(System.Web.Configuration.WebConfigurationManager.AppSettings("pathAD"), System.Web.Configuration.WebConfigurationManager.AppSettings("userAD"), System.Web.Configuration.WebConfigurationManager.AppSettings("passAD"))
        Return de
    End Function

    ''' <summary>
    ''' Verifica si un usuario es miembro del grupo de AD
    ''' </summary>
    Private Shared Function ifMemberOfAGroup(ByVal grouptoCheck As String, ByVal userName As String) As Boolean
        'Try
        Dim myDE As DirectoryEntry = GetDirectoryEntry()
        grouptoCheck = grouptoCheck.ToLower()
        Dim myDirectorySearcher As New DirectorySearcher(myDE)
        myDirectorySearcher.Filter = "sAMAccountName=" & userName
        myDirectorySearcher.PropertiesToLoad.Add("memberOf")
        Dim myresult As SearchResult = myDirectorySearcher.FindOne()
        Dim NumberOfGroups As Integer = myresult.Properties("memberOf").Count() - 1
        Dim tempString As String
        Dim varAux As Boolean = False
        While (NumberOfGroups >= 0)
            tempString = myresult.Properties("memberOf").Item(NumberOfGroups)
            tempString = tempString.Substring(0, tempString.IndexOf(",", 0))
            tempString = tempString.Replace("CN=", "")
            'Quitamos CN= del nombre del grupo
            tempString = tempString.ToLower() 'se colocan a minusculas
            tempString = tempString.Trim()
            If (grouptoCheck = tempString) Then
                varAux = True
                NumberOfGroups = 0 ' si existe el usuario en el grupo q le indicamos, sale del while y retorna true
            End If
            NumberOfGroups = NumberOfGroups - 1
        End While
        Return varAux
        'Catch ex As Exception
        ' End Try
    End Function

    ''' <summary>
    ''' devuelve una lista de  clUsuarioAD con el nombre de los grupos encontrados en el AD
    ''' </summary>
    Public Shared Function getGroupsAD() As List(Of clUsuarioAD)
        Dim list As New List(Of clUsuarioAD)
        Dim myDE As DirectoryEntry = GetDirectoryEntry()
        Dim mySearcher As New DirectorySearcher(myDE)
        Dim filter As StringBuilder = New StringBuilder()
        filter.Append("objectClass=group")
        mySearcher.Filter = filter.ToString
        mySearcher.SearchScope = DirectoryServices.SearchScope.Subtree
        Try
            Dim myresult As SearchResultCollection = mySearcher.FindAll()
            For Each result As SearchResult In myresult
                Dim dey As DirectoryEntry = result.GetDirectoryEntry
                list.Add(New clUsuarioAD(dey.Properties("sAMAccountName").Value.ToString))
                dey.Close()
            Next
        Catch ex As Exception
            If Not ex.GetType Is GetType(System.NullReferenceException) Then
                list.Add(New clUsuarioAD(ex.Message.ToString))
            End If
        End Try
        Return list
    End Function
    ''' <summary>
    '''  devuelve una lista de  clUsuarioAD encontrados en el AD
    ''' </summary>
    Public Shared Function getUsuariosAD(Optional ByVal grupo As String = "0", Optional ByVal nomreUsr As String = "") As List(Of clUsuarioAD)
        Dim list As New List(Of clUsuarioAD)
        'Try
        Dim de As DirectoryEntry = GetDirectoryEntry()
        Dim ds As DirectorySearcher = New DirectorySearcher(de)
        Dim filter As StringBuilder = New StringBuilder()
        filter.Append("(&(objectCategory=Person)(objectClass=user))")
        ds.Filter = filter.ToString()
        ds.SearchScope = DirectoryServices.SearchScope.Subtree
        ds.PropertiesToLoad.Add("userPrincipalName")
        'ds.PropertiesToLoad.Add("displayName")
        '   ds.PropertiesToLoad.Add("sAMAccountName")
        Dim results As SearchResultCollection = ds.FindAll()

        For Each result As SearchResult In results
            ' Dim activo As String = ""
            Dim dey As DirectoryEntry = result.GetDirectoryEntry
            Dim dominio As String = ""
            Dim props As ResultPropertyCollection = result.Properties
            For Each propName As String In props.PropertyNames
                'If propName.ToLower = "useraccountcontrol" Then
                '    activo = props(propName)(0)
                'End If
                If String.IsNullOrEmpty(dominio) And (propName.ToLower = "userprincipalname" Or propName.ToLower = "adspath") Then
                    dominio = props(propName)(0)
                End If
            Next

            Dim activo As String = dey.Properties("userAccountControl").Value.ToString
            If Val(activo) <> enEstadosUsuarios.Inactivo Then
                Dim arrDominio() As String
                If dominio.Contains("@") Then
                    arrDominio = Split(dominio, "@")
                Else
                    arrDominio = Split(dominio, "//")
                End If
                If arrDominio.Length > 1 Then
                    arrDominio = Split(arrDominio.GetValue(1), ".")
                Else
                    arrDominio = Split(arrDominio.GetValue(0), ".")
                End If

                dominio = arrDominio.GetValue(0) & "\"
                Dim userName As String = ""
                userName = dey.Properties("sAMAccountName").Value.ToString
                Dim nombre As String = ""
                ' nombre = dey.Properties("displayName").Value.ToString()

                'Dim nombreapellido As String = dey.Properties("sAMAccountFullName").Value.ToString
                If String.IsNullOrEmpty(userName) = False Then
                    nombre = getNombreCompleto(userName)
                    ' If nombre.Length > 0 Then nombre = nombre.ToLower
                    If String.IsNullOrEmpty(nombre) Then nombre = userName

                    If grupo <> "0" Then

                        If ifMemberOfAGroup(grupo, userName) Then
                            If Trim(nomreUsr) <> "" Then
                                If (dominio & userName).Contains(nomreUsr) Or nombre.ToLower.Contains(nomreUsr.ToLower) Then
                                    list.Add(New clUsuarioAD(dominio & userName, userName))
                                End If
                            Else
                                list.Add(New clUsuarioAD(dominio & userName, userName))
                            End If

                        End If
                    Else
                        If Trim(nomreUsr) <> "" Then
                            If (dominio & userName).Contains(nomreUsr) Or nombre.ToLower.Contains(nomreUsr.ToLower) Then
                                list.Add(New clUsuarioAD(dominio & userName, userName))
                            End If
                        Else
                            list.Add(New clUsuarioAD(dominio & userName, userName))
                        End If
                    End If
                End If
            End If

            dey.Close()
        Next result
        de.Close()
        'Catch ex As Exception
        '    list.Add(New clUsuarioAD(ex.Message.ToString & ex.StackTrace))
        'End Try
        Return list
    End Function

    Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
        Return Me.Usuario.CompareTo(obj.Usuario)
    End Function

    Public Shared Function getNombreCompleto(ByVal usuario As String) As String
        Dim user As String = ""
        Try
            Dim de As DirectoryEntry = GetDirectoryEntry()
            Dim ds As DirectorySearcher = New DirectorySearcher(de)
            Dim filter As StringBuilder = New StringBuilder()
            'filter.Append("(&(objectCategory=Person)(objectClass=user))")
            ds.Filter = filter.ToString()
            ds.Filter = "sAMAccountName=" + usuario
            ds.SearchScope = DirectoryServices.SearchScope.Subtree
            ds.PropertiesToLoad.Add("displayName")
            '   ds.PropertiesToLoad.Add("sAMAccountName")
            Dim results As SearchResultCollection = ds.FindAll()

            For Each result As SearchResult In results
                Dim dey As DirectoryEntry = result.GetDirectoryEntry
                Dim dominio As String = ""
                user = dey.Properties("displayName").Value
                dey.Close()
            Next result
            de.Close()
        Catch ex As Exception
            user = ""
        End Try
        Return user
    End Function

    Private Sub cargarDatos(ByVal usuario As String)
        Dim user As String = ""

        Dim de As DirectoryEntry = GetDirectoryEntry()
        Dim ds As DirectorySearcher = New DirectorySearcher(de)
        Dim filter As StringBuilder = New StringBuilder()
        'filter.Append("(&(objectCategory=Person)(objectClass=user))")
        ds.Filter = filter.ToString()
        ds.Filter = "sAMAccountName=" + usuario
        ds.SearchScope = DirectoryServices.SearchScope.Subtree
        ds.PropertiesToLoad.Add("displayName")
        '   ds.PropertiesToLoad.Add("sAMAccountName")
        Dim results As SearchResultCollection = ds.FindAll()

        For Each result As SearchResult In results
            Dim dey As DirectoryEntry = result.GetDirectoryEntry
            Dim dominio As String = ""
            _nombreCompleto = dey.Properties("displayName").Value
            _userAccountControl = Val(dey.Properties("userAccountControl").Value)
            _userPrincipalName = dey.Properties("userPrincipalName").Value
            _email = dey.Properties("mail").Value
            _company = dey.Properties("company").Value
            _homephone = dey.Properties("homephone").Value
            _mobile = dey.Properties("mobile").Value
            _streetAddress = dey.Properties("streetAddress").Value
            dey.Close()
        Next result
        de.Close()


    End Sub

    Public Shared Function getEmail(ByVal usuario As String) As String
        Dim mail As String = ""
        Try
            Dim de As DirectoryEntry = GetDirectoryEntry()
            Dim ds As DirectorySearcher = New DirectorySearcher(de)
            Dim filter As StringBuilder = New StringBuilder()
            'filter.Append("(&(objectCategory=Person)(objectClass=user))")
            ds.Filter = filter.ToString()
            ds.Filter = "sAMAccountName=" + usuario
            ds.SearchScope = DirectoryServices.SearchScope.Subtree
            ds.PropertiesToLoad.Add("mail")
            '   ds.PropertiesToLoad.Add("sAMAccountName")
            Dim results As SearchResultCollection = ds.FindAll()

            For Each result As SearchResult In results
                Dim dey As DirectoryEntry = result.GetDirectoryEntry
                Dim dominio As String = ""
                mail = dey.Properties("mail").Value
                dey.Close()
            Next result
            de.Close()
        Catch ex As Exception
        End Try
        Return mail
    End Function

    Private Enum enEstadosUsuarios As Integer
        ' Used to disable an account.
        Activo = 512
        Inactivo = 66050
    End Enum


End Class